package com.hissy.common.office.exporter;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

/**
 * 导出工具类
 */
public class ExportUtil {

    // region 导出器列表

    static List<ExporterInfo> exporterInfoList = new ArrayList<>();

    static class ExporterInfo {
        public ExportType type;
        public String extension;
        public FuncWithException<DataExporter> newInstanceFunc;
    }

    static void addExporter(
        ExportType type,
        String extension,
        FuncWithException<DataExporter> newInstanceFunc
    ) {
        ExporterInfo exporterInfo = new ExporterInfo();
        exporterInfo.type = type;
        exporterInfo.extension = extension;
        exporterInfo.newInstanceFunc = newInstanceFunc;
        exporterInfoList.add(exporterInfo);
    }

    static {
        addExporter(ExportType.XLS, "xls", () -> new XlsDataExporter());
    }

    // endregion

    /**
     * 获取文件后缀
     *
     * @param type 导出类型
     * @return 文件后缀
     */
    public static String getExtension(ExportType type) {
        for (ExporterInfo exporterInfo : exporterInfoList) {
            if (type == exporterInfo.type) {
                return exporterInfo.extension;
            }
        }

        return null;
    }

    /**
     * 导出到文件
     *
     * @param table 表格内容
     * @param type  文件类型
     */
    public static void export(ExportTable table, ExportType type, String localPathWithoutExtension) {
        byte[] content = export(table, type);
        try {
            Files.write(Paths.get(localPathWithoutExtension + "." + getExtension(type)), content);
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
    }

    /**
     * 导出成文件二级制
     *
     * @param table 表格内容
     * @param type  文件类型
     * @return 文件二级制
     */
    public static byte[] export(ExportTable table, ExportType type) {
        try {

            // 构建导出器
            DataExporter exporter = null;
            for (ExporterInfo exporterInfo : exporterInfoList) {
                if (type == exporterInfo.type) {
                    exporter = exporterInfo.newInstanceFunc.invoke();
                    break;
                }
            }

            // 导出数据
            assert exporter != null;
            exporter.writeRow(table.columns);
            for (String[] row : table.rows) {
                exporter.writeRow(row);
            }

            return exporter.getBytes();

        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }

}
